use super::Criterion;
use crate::Var;

pub struct RMSE();

impl RMSE {
    pub fn new() -> Self {
        Self()
    }
}

impl Criterion for RMSE {
    fn loss(&self, predicted: &[crate::Var], target: &[crate::Var]) -> Var {
        assert_eq!(predicted.len(), target.len());
        let n = predicted.len();
        let loss = predicted.iter().zip(target.iter())
            .map(|(p, t)| -> Var { (p - t).pow(2.) })
            .sum::<Var>() / n as f64;
        loss.sqrt()
    }
}